package cruncher;

import java.io.BufferedOutputStream;
import java.io.BufferedWriter;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Collections;
import java.util.PriorityQueue;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;

public class SolutionPool implements ISolutionPool {
	private PriorityQueue<Solution> pool = new PriorityQueue<Solution>();
	private Timer loggingTimer;
	private String filepath;
	private BufferedWriter writer;
	private boolean logResults = false;
	
    public SolutionPool() {
    	if (!logResults) return;
    	filepath = String.format("results.%d.txt", System.currentTimeMillis()); 
    	try {
			writer = Files.newBufferedWriter(Paths.get(filepath), StandardCharsets.UTF_8);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    	loggingTimer = new Timer();
        loggingTimer.schedule(new LogResultsTask(), 0, 10 * 1000);
	}

    class LogResultsTask extends TimerTask {
    	double timeStarted = System.currentTimeMillis();
    	public void run() {
    		

        	int timeElapsedSec = (int)(System.currentTimeMillis() - timeStarted) / 1000;
            try {
            	if (pool.peek() == null)
            	{
            		writer.write(String.format("%d,n/a", timeElapsedSec));
            	}
            	else
            	{
            		writer.write(String.format("%d,%f", timeElapsedSec, pool.peek().getObjValue()));
            	}
				writer.newLine();
				writer.flush();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
        }
    }
    
	@Override
	public void addSolution(Solution s) {
		pool.offer(s);
		
	}

	@Override
	public Solution getRandom() {
		if (pool.isEmpty()) return null;
		Random rnd = new Random(System.currentTimeMillis());
		Solution[] solutions = pool.toArray(new Solution[0]);
		return solutions[rnd.nextInt() % solutions.length];
	}

	@Override
	public boolean isBetterSolution(Solution next) {
		if (next == null) return false;
		if (this.getMin() == null) return true;
		return (next.getObjValue() < getMin().getObjValue()) ;
	}

	@Override
	public Solution getMin() {
		return pool.peek();
	}

	@Override
	public Solution getMax() {
		return Collections.max(pool, pool.comparator());
	}

	@Override
	public int size() {
		return pool.size();
	}

	@Override
	public void replaceSolution(Solution oldS, Solution newS) {
		// TODO Auto-generated method stub
		
	}

}
